home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / byte0387.arc / EDGE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1985-07-12  |  5.7 KB  |  161 lines

  1.  
  2. /* 
  3.  *              edge.c
  4.  *
  5.  * This program will read in an image file, apply a simple edge detection
  6.  * algorithm to it and then write out the resulting file. It demonstrates
  7.  * the use of color on the output file to indicate edges.
  8.  *
  9.  * Usage edge input.image output.image threshold
  10.  * 
  11.  * At all pixels where there is a difference equal to or greater than 
  12.  * "threshold" that pixel will be set to red. Other pixels left intact.
  13.  *
  14.  * This program is based on the Sobel edge detection algorithm, it uses the
  15.  * fact that objects in an image are usually delineated by sharp changes in
  16.  * intensity. The image is processed by picking 8 adjacent pixels and treating
  17.  * them as a 3 X 3 array. The array can be represented as follows :
  18.  *
  19.  *      | a b c |
  20.  *      | d e f |
  21.  *      | g h i |
  22.  *
  23.  * And there are four unique straightline paths through this array which pass
  24.  * through the center pixel. They can be represented as :
  25.  *
  26.  *      g -> e -> c
  27.  *      d -> e -> f
  28.  *      a -> e -> i
  29.  *      b -> e -> h
  30.  *
  31.  * The algorithm treats the three pixels as points on a line described by the
  32.  * function : Intensity = M * x + C. The parameter of interest is the slope
  33.  * of the function M. The sharper the transition in intensity, the larger the
  34.  * value of the slope. This is compared to the threshold and if it exceeds it
  35.  * the pixel e is considered to lie on an edge and is marked as such.
  36.  *
  37.  */
  38.  
  39. #include <exec/types.h>
  40. #include <exec/memory.h>
  41. #include <stdio.h>
  42. #include <fcntl.h>
  43.  
  44. /* This array describes the relative offsets of adjacent pixels that make up
  45.  * the edge of interest. 
  46.  */
  47. static int edges[] =  {
  48.                          -1, 1,  1,-1,  /* g and c */
  49.                          -1, 0,  1, 0,  /* d and f */
  50.                          -1,-1,  1, 1,  /* a and i */
  51.                           0,-1,  0, 1   /* b and h */
  52.                         };
  53.  
  54.  
  55. void main(argc,argv)
  56. int argc;
  57. char *argv[];
  58.  
  59. {
  60.   UBYTE *image,*simage; /* An array for our image               */
  61.   USHORT colors[16];    /* The color map                        */
  62.   int   i,ii,j,         /* Some counters                        */
  63.         thresh,         /* The edge threshold                   */
  64.         edgepixels,     /* The number of edge pixels found      */
  65.         x,y,m,p1,p2,    /* Image coordinates                   */
  66.         x1,x2,y1,y2;    /* Edge boundary coordinates           */
  67.         
  68.  
  69.   printf("Simple edge analysis program.\n");
  70.   if (argc != 4) {
  71.     printf("usage is Edge infile outfile threshold\n");
  72.     exit(10);
  73.   }
  74.   thresh = atoi(argv[3]);
  75.   if ((thresh < 0) || (thresh > 15)) {
  76.     printf("Illegal threshold value, use a number between 0 and 15\n");
  77.    exit(10);
  78.   }
  79.   printf("Using Threshold value %d.\n",thresh);
  80.  
  81.   /* Buffer for one image + 4 lines. The algorithm below will store the 
  82.    * resulting image into the image buffer - 4 lines. That way we do not
  83.    * need to allocate two complete image buffers. The allocate call will
  84.    * also set the array to zero.
  85.    */
  86.   image = (UBYTE *)AllocMem(129280,MEMF_CLEAR); 
  87.   
  88.   if (image == NULL) {
  89.     printf("Sorry couldn't allocate the image buffer! \n");
  90.     exit(10);
  91.   }
  92.   simage = image + 1280; /* Source image resides four lines below image */
  93.  
  94.   /* First we read in the source image */
  95.   i = ReadImage(argv[1],simage,colors);
  96.   if (i != 0) {
  97.      printf("Error reading in the source image.\n");
  98.      FreeMem(image,129280);
  99.      exit(10);
  100.   }
  101.  
  102.   /* Now do what ever image processing we wish on the image data */
  103.  
  104.   printf("Processing the source image \n");
  105.   edgepixels = 0;
  106.   /* First copy the first row of pixels to the destination */
  107.   for (i=0; i<640; i++) {
  108.     j = Pixel(simage,i,0) - 1;
  109.     if ((j < 0) || (j > 14)) j = 0;
  110.     SetPixel(image,i,0,j);
  111.   }
  112.   for (y=1; y<399; y++) {   
  113.     printf("Line %d\x0d",y);
  114.     /* Move a line from the Source image to the Destination Image */
  115.     for (i=0; i<640; i++) {
  116.       j = Pixel(simage,i,y) - 1;
  117.       if ((j < 0) || (j > 14)) j = 0;
  118.       SetPixel(image,i,y,j);
  119.     }
  120.     /* Now analyze each pixel in this line */
  121.     for (x=1; x<639; x++) { 
  122.       /* (x,y) is the center pixel in a 3X3 square */
  123.       chkabort();       /* Added in case the user wants to abort */
  124.       for (j=0; j<4; j++) { /* Check for four types of edges */
  125.         /* Note the indirection through the color map since Pixel returns
  126.          * the colormap entry this pixel uses, the colormap actually
  127.          * contains its intensity. Also since all color map entries are
  128.          * shades of gray R = G = B and the intensity is logically ANDed
  129.          * to mask off the R and G components leaving only the B value
  130.          * which will always be between 0 and 15.
  131.          */
  132.         x1 = x + edges[j*4];
  133.         y1 = y + edges[j*4+1];
  134.         x2 = x + edges[j*4+2];
  135.         y2 = y + edges[j*4+3];
  136.         p1 = colors[Pixel(simage,x2,y2)] & 0xf;
  137.         p2 = colors[Pixel(simage,x1,y1)] & 0xf;
  138.         m = abs(p1 - p2);
  139.         if (m > thresh) {
  140.           edgepixels++;
  141.           SetPixel(image,x,y,15);
  142.           break;
  143.         } /* if we crossed the threshold */
  144.       } /* for each value of j */
  145.     } /* For x */
  146.   } /* for y */
  147.   printf("\n Done.\n");
  148.   printf(" Set the value for %d edge pixels\n",edgepixels);
  149.   /* Now we fix up the color map because we have shifted all of the pixels
  150.    * down by one in the color map to make room for our edge color (red)
  151.    */
  152.   for (i=1; i<15; i++) colors[i-1] = colors[i];
  153.   colors[15] = 0x0f00;  /* Set edge pixels to red */
  154.   /* Then we write out the image */
  155.   i = WriteImage(argv[2],image,colors);
  156.   if (i != 0) printf("Error writing the output file!\n");
  157.   FreeMem(image,129280);
  158.   exit(i);
  159. }
  160.  
  161.